import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';

import { en_US, zh_CN, NzI18nService } from 'ng-zorro-antd';
import * as df_en from 'date-fns/locale/en';
import * as df_zh_cn from 'date-fns/locale/zh_cn';
import { TranslateService } from '@ngx-translate/core';
import { SettingsService, AlainI18NService } from '@delon/theme';

@Injectable()
export class I18NService implements AlainI18NService {

  private _langs = [
    { code: 'en', text: 'English' },
    { code: 'zh-CN', text: '中文' },
  ];
  private _default = 'zh-CN';
  private change$ = new BehaviorSubject<string>(null);

  constructor(
    setSrv: SettingsService,
    private nzI18nSrv: NzI18nService,
    private translSrv: TranslateService,
  ) {
    const lans: string[] = this._langs.map(item => item.code),
      browserLang: string = lans.find(
        item => item.includes(translSrv.getBrowserLang())
      );
    translSrv.addLangs(lans);
    this._default = setSrv.layout.lang || browserLang || this._default;
    setSrv.setLayout('lang', this._default);
    this.setZorro(this._default).setDateFns(this._default);
  }

  public setZorro(lang: string): this {
    this.nzI18nSrv.setLocale(lang === 'en' ? en_US : zh_CN);
    return this;
  }

  public setDateFns(lang: string): this {
    (window as any).__locale__ = lang === 'en' ? df_en : df_zh_cn;
    return this;
  }

  public get change(): Observable<string> {
    return this.change$.asObservable().pipe(filter(w => w != null));
  }

  public use(lang: string): void {
    lang = lang || this.translSrv.getDefaultLang();
    if (this.currentLang === lang) return;
    this.setZorro(lang).setDateFns(lang);
    this.translSrv.use(lang).subscribe(() => this.change$.next(lang));
  }

  /** 获取语言列表 */
  public getLangs() {
    return this._langs;
  }

  /** 翻译 */
  public fanyi(key: string) {
    return this.translSrv.instant(key);
  }

  /** 默认语言 */
  public get defaultLang() {
    return this._default;
  }

  /** 当前语言 */
  public get currentLang() {
    return (this.translSrv.currentLang || this._default);
  }
}